package com.qfedu.microuser.user.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qfedu.api.coupon.feign.CouponInfoFeignService;
import com.qfedu.common.core.entity.User;
import com.qfedu.common.core.enums.ProductTypeEnum;
import com.qfedu.common.core.exception.CommonException;
import com.qfedu.common.core.utils.JwtUtils;
import com.qfedu.common.core.utils.UserUtils;
import com.qfedu.common.minio.utils.MinioUtil;
import com.qfedu.common.mq.dto.RegisterDTO;
import com.qfedu.common.mq.utils.RocketMqUtils;
import com.qfedu.common.redis.enums.RedisKeyEnum;
import com.qfedu.common.redis.utils.RedisCache;
import com.qfedu.microuser.pointinfo.service.PointInfoService;
import com.qfedu.microuser.user.mapper.UserMapper;
import com.qfedu.microuser.user.param.LoginParam;
import com.qfedu.microuser.user.param.RegisterParam;
import com.qfedu.microuser.user.service.UserService;
import com.qfeud.common.sms.enums.AliSmsEnum;
import com.qfeud.common.sms.utils.AliSmsUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Classname UserServiceImpl
 * @Description TODO
 * @Date 2025-09-22 16:11
 * @Created by 老任与码
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private MinioUtil minioUtil;

    @Resource
    private RedisCache redisCache;

    @Resource
    private ThreadPoolExecutor threadPoolExecutor;

    @Resource
    private PointInfoService pointInfoService;

    @Resource
    private CouponInfoFeignService couponInfoFeignService;

    @Resource
    private RocketMqUtils rocketMqUtils;

    @Override
    public String login(LoginParam loginParam) {
//        if(loginParam.getUsername() == null || loginParam.getUsername().isEmpty()){
//            throw new CommonException("请输入用户名");
//        }
        User user = userMapper.selectOne(Wrappers.lambdaQuery(User.class)
                .eq(User::getUsername, loginParam.getUsername()));
        if (user == null) {
            throw new CommonException("用户名错误");
        }
        String md5Password = SecureUtil.md5(loginParam.getPassword());
        if (!user.getPassword().equals(md5Password)) {
            throw new CommonException("密码错误");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("uid", user.getId());
        return JwtUtils.createJwt(map);

    }

    @Override
    public String uploadAvatar(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        String uuid = UUID.randomUUID().toString().replace("-", "");
        String fileName = uuid + originalFilename.substring(originalFilename.lastIndexOf("."));

        try {
            String path = minioUtil.upload(file.getInputStream(), fileName);
            return path;
        } catch (IOException e) {
            throw new CommonException("上传头像异常");
        }
    }

    @Override
    public User userInfo() {
        // Integer uid = TokenUtils.getUidFromToken();
        Integer uid = UserUtils.getUid();
        return userMapper.selectById(uid);
    }

    @Override
    public void sendCode(String phone) {

        String code = RandomUtil.randomNumbers(6);
        // 异步发送验证码短信
        threadPoolExecutor.execute(() -> {
            AliSmsUtils.sendSms(
                    AliSmsEnum.SMS_CODE.getSignName(),
                    AliSmsEnum.SMS_CODE.getTemplateCode(),
                    phone,
                    code);
        });

        // 将验证码存入redis的string类型中
        // String.format("code:%s", phone);
        String key = String.format(RedisKeyEnum.KEY_CODE.getKey(), phone);
        redisCache.setCacheObject(key, code, RedisKeyEnum.KEY_CODE.getExpire(), TimeUnit.SECONDS);
    }

    // seata提供的全局事务注解
    // rollbackFor = Exception.class 防止抛出非运行时异常，造成事务失效的情况
    // @GlobalTransactional(rollbackFor = Exception.class)
    @Override
    public void register(RegisterParam registerParam) {

        // 验证验证码是否正确
        /*
        String key = String.format(RedisKeyEnum.KEY_CODE.getKey(), registerParam.getPhone());
        String redisCode = redisCache.getCacheObject(key);
        if (!StringUtils.hasLength(redisCode)) {
            throw new CommonException("验证码不存在或已过期");
        }
        if (!registerParam.getCode().equals(redisCode)) {
            throw new CommonException("输入的验证码错误");
        }
        */

        User user = new User();
        BeanUtils.copyProperties(registerParam, user);

        user.setPassword(SecureUtil.md5(registerParam.getPassword()));



        // 获取父用户
//        User parentUser = userMapper.selectOne(Wrappers.lambdaQuery(User.class)
//                .eq(User::getInviteCode, registerParam.getInviteCode()));
//        if (parentUser == null) {
//            throw new CommonException("邀请码错误");
//        }
//        user.setPid(parentUser.getId());
//
//        String inviteCode = RandomUtil.randomString(6);
//        user.setInviteCode(inviteCode);
//
//        // 生成用户邀新的二维码
//        String qrUrl = createQrCode(registerParam.getInviteCode());
//        user.setQrcodeUrl(qrUrl);
//
        userMapper.insert(user);
//
//        // 领取优惠券
//        // 如果进行了远程调用，一般根据返回的结果进行相应的处理
//        /*
//        R r = couponInfoFeignService.distributeCoupon(ProductTypeEnum.PRODUCT_REGISTER.getType(), user.getId());
//        if (r.getCode() != CommonConstants.SUCCESS) {
//            throw new CommonException(r.getMsg());
//        }
//
//        int a = 10 / 0;
//        */
//        RegisterDTO registerDTO = new RegisterDTO();
//        registerDTO.setUid(user.getId());
//        registerDTO.setProductType(ProductTypeEnum.PRODUCT_REGISTER);
//        System.out.println("发送消息：" + registerDTO);
//        // 发送消息，对象转为json字符串
//        rocketMqUtils.sendSyncMsg("topic_register", null, JSON.toJSONString(registerDTO));
//
//        // 邀请人送积分，如果送积分的结果，不影响注册的结果，考虑异步送积分
//        // 思考问题：如果异步送积分失败怎么办？
//        // 进行数据补偿，常规套路：将补偿数据写入补偿表，使用定时任务定时扫表补偿
//        threadPoolExecutor.execute(() -> {
//            pointInfoService.addPointBy(parentUser.getId(), 1);
//        });
        
    }

    private String createQrCode(String inviteCode) {
        // 生成二维码
        String url = "http://www.qfedu.com?inviteCode=" + inviteCode;
        // QrCodeUtil.generate(url, 300, 300, FileUtil.file("d:/qrcode.png"));

        BufferedImage bufferedImage = QrCodeUtil.generate(url, 300, 300);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        // 将图像输出到输出流中。
        try {
            ImageIO.write(bufferedImage, "jpeg", bos);
            // 获取二维码图片的输入流对象
            InputStream inputStream = new ByteArrayInputStream(bos.toByteArray());
            // 上传
            String fileName = UUID.randomUUID().toString().replace("-", "") + ".jpg";
            return minioUtil.upload(inputStream, fileName);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void updatePointById(Integer id, Integer addPoint) {
        userMapper.update(null, Wrappers.<User>lambdaUpdate()
                .setSql("point=point+" + addPoint)
                .eq(User::getId, id));
    }
}
